﻿using SharpKit.JavaScript;

namespace XWeb.SharpKit.Razor
{
	/// <summary>
	/// Abstract base class of html area to render in JavaScript. Supports escaping special html symbols.
	/// </summary>
	/// <typeparam name="T">Type of the model.</typeparam>
	[JsType(JsMode.Prototype)]
	public abstract class HtmlArea<T>: JsContext, IRenderingArea<T>
	{
		private string _result = "";

		/// <summary>
		/// Result of rendering the area.
		/// </summary>
		public string Result { get { return _result; } }

		[JsField(Export = false)]
		private T _model;

		/// <summary>
		/// Model of the area.
		/// </summary>
		public T Model { get { return _model; } set { _model = value; } }

		[JsProperty(Export = false)]
		object IRenderingArea.Model { get { return Model; } set { Model = value.As<T>(); } }

		/// <summary>
		/// Writes a value to the area result stream while executing. Escapes special html symbols.
		/// </summary>
		/// <param name="value">Some value to write.</param>
		protected virtual void Write(object value)
		{
			if (value != null)
				_result += EscapeValue(value.As<JsObject>().toString());
		}

		/// <summary>
		/// Escapes special html symbols.
		/// </summary>
		/// <param name="value">String to escape.</param>
		/// <returns>Escaped string.</returns>
		protected virtual string EscapeValue(JsString value)
		{
			return value
				.replace("&", "&amp;")
				.replace("<", "&lt;")
				.replace(">", "&gt;")
				.replace("\"", "&quot;")
				.replace("'", "&#39;");
		}

		/// <summary>
		/// Writes a literal to the area's result stream while executing. Does not escapes html symbols.
		/// </summary>
		/// <param name="value"></param>
		protected virtual void WriteLiteral(string value)
		{
			_result += value;
		}

		/// <summary>
		/// Executes rendering the area.
		/// </summary>
		public abstract void Execute();
	}
}
